package xpn.platform.modules.workflow.runtime.history;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.config.Projection;
import xpn.platform.common.repository.XpnRepository;
import xpn.platform.modules.workflow.runtime.instance.Instance;
import xpn.platform.modules.workflow.runtime.todo.Todo;

import java.util.List;

/**
 * The interface History dao.
 */
@RepositoryRestResource(path = "workflow_runtime_histories", excerptProjection = HistoryDefaultProjection.class)
public interface HistoryDAO extends XpnRepository<History, Long> {
    /**
     * 根据流程实例Id 获取流程记录
     *
     * @param id 流程实例Id
     * @return 流程记录列表
     */
    List<History> findByInstanceIdOrderByCreatedTime(Long id);

    /**
     * 根据接收人待办Id查询流程记录
     *
     * @param id 接收人待办Id
     * @return 流程记录
     */
//    @Query(value = "SELECT h.* FROM wf_ru_history h WHERE h.sendee_todo_id=?1 LIMIT 1", nativeQuery = true)
    History findFirstBySendeeTodoId(Long id);

    /**
     * 查询指定已办可收回的列表，空列表代表不可收回
     * 如果流程记录接收人的待办为空(结束代办的情况)  或者接收人的待办未结束并且接受人不存在历史记录(发送了一个人或者几个人) 可收回
     * not exists 子查询的意图：接收人没有继续往下发送，
     * 如果接收人继续发送，就会存在 execution_todo_id 等于查询的 wf_ru_history 的 sendee_todo_id 的新 wf_ru_history
     *
     * @param todoId 已办Id
     * @return 可收回的 History 列表
     */
    @Query(value = "SELECT h.* FROM wf_ru_history h " +
            "left JOIN wf_ru_todo t ON " +
            "t.id=h.sendee_todo_id " +
            "INNER JOIN wf_action a ON " +
            "a.id=h.action_id " +
            "AND a.can_take_back=1 " +
            "AND (a.action_type=1 OR a.action_type=2 or a.action_type=0) " +
            "WHERE h.execution_todo_id=?1 AND " +
            "((t.completed=0  and  (SELECT count(*) FROM wf_ru_history oh " +
            "INNER JOIN wf_ru_todo ot ON " +
            "ot.id=oh.sendee_todo_id " +
            "WHERE oh.execution_todo_id=h.sendee_todo_id " +
            "AND oh.action_id IS NOT NULL AND ot.completed=0)=0) " +
            "or h.sendee_todo_id is null)",
            nativeQuery = true)
    List<History> queryTakeBack(Long todoId);
}

/**
 * 缺省投影
 *
 * @author duwei
 */
@Projection(name = "default", types = {History.class})
interface HistoryDefaultProjection {

    Long getId();

    Instance getInstance();

    String getExecutorId();

    String getExecutorName();

    String getExecutionStateName();

    Long getActionId();

    String getActionName();

    String getSendeeId();

    String getSendeeName();

    Todo getExecutionTodo();

    Todo getSendeeTodo();
}

/**
 * 列表投影，用于返回关联属性
 *
 * @author duwei
 */
@Projection(name = "list", types = {History.class})
interface HistoryListProjection {
    Long getId();

    @Value("#{target.instance != null ? target.instance.id : null}")
    Long getInstanceId();

    @Value("#{target.executionTodo != null ? target.executionTodo.id : null}")
    Long getExecutionTodoId();

    @Value("#{target.sendeeTodo != null ? target.sendeeTodo.id : null}")
    Long getSendeeTodoId();

    String getExecutorId();

    String getExecutorName();

    String getExecutionStateName();

    Long getActionId();

    String getActionName();

    String getSendeeId();

    String getSendeeName();
}